home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-08-16 | 29.1 KB | 1,312 lines |
- head 1.10;
- branch ;
- access ;
- symbols ;
- locks shirriff:1.10; strict;
- comment @ * @;
-
-
- 1.10
- date 91.08.15.23.13.46; author ouster; state Exp;
- branches ;
- next 1.9;
-
- 1.9
- date 91.01.08.21.36.35; author tve; state Exp;
- branches ;
- next 1.8;
-
- 1.8
- date 89.01.20.09.02.45; author ouster; state Exp;
- branches ;
- next 1.7;
-
- 1.7
- date 89.01.13.17.03.53; author ouster; state Exp;
- branches ;
- next 1.6;
-
- 1.6
- date 89.01.11.14.28.04; author ouster; state Exp;
- branches ;
- next 1.5;
-
- 1.5
- date 88.12.29.14.48.45; author ouster; state Exp;
- branches ;
- next 1.4;
-
- 1.4
- date 88.12.29.10.17.56; author ouster; state Exp;
- branches ;
- next 1.3;
-
- 1.3
- date 88.12.29.09.40.37; author ouster; state Exp;
- branches ;
- next 1.2;
-
- 1.2
- date 88.12.28.16.34.38; author ouster; state Exp;
- branches ;
- next 1.1;
-
- 1.1
- date 88.12.23.17.22.16; author ouster; state Exp;
- branches ;
- next ;
-
-
- desc
- @@
-
-
- 1.10
- log
- @Changes to index creation.
- (Checked in by shirriff)
- @
- text
- @/*
- * man.c --
- *
- * This file contains the "man" program for Sprite. See the man
- * page for details on how it works.
- *
- * Copyright 1988 Regents of the University of California
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies. The University of California
- * makes no representations about the suitability of this
- * software for any purpose. It is provided "as is" without
- * express or implied warranty.
- */
-
- #ifndef lint
- static char rcsid[] = "$Header: /sprite/src/cmds/man/RCS/man.c,v 1.9 91/01/08 21:36:35 tve Exp Locker: ouster $ SPRITE (Berkeley)";
- #endif not lint
-
- #include <ctype.h>
- #include <errno.h>
- #include <option.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/file.h>
- #include <sys/stat.h>
-
- /*
- * Name of default configuration file:
- */
-
- #ifndef CONFIG_FILE
- #define CONFIG_FILE "/sprite/lib/man/config"
- #endif
-
- /*
- * Information related to command-line options:
- */
-
- int typeset = 0; /* Non-zero means print on typesetter
- * instead of on terminal. */
- int noMore = 0; /* Non-zero means don't filter output through
- * the "more" program. */
- char *sectionName = NULL; /* Name of section to search in. */
- char *configFile = CONFIG_FILE; /* Configuration file that describes where
- * man pages are located. */
- int reformat = 0; /* Non-zero means reformat man page even if
- * formatted copy appears to be up-to-date. */
- int makeIndex = 0; /* Non-zero means generate index from args
- * rather than printing man pages. */
- int keywordLookup = 0; /* Non-zero means "man -k": look for
- * keywords. */
- int where = 0; /* Non-zero means say where man page is. */
-
- Option optionArray[] = {
- {OPT_STRING, "c", (char *) &configFile,
- "Name of configuration file (default: /sprite/lib/man/config)"},
- {OPT_TRUE, "f", (char *) &keywordLookup,
- "Identical to \"-k\" (provided for UNIX compatibility)"},
- {OPT_TRUE, "i", (char *) &makeIndex,
- "Generate index from file name arguments"},
- {OPT_TRUE, "k", (char *) &keywordLookup,
- "Print index information for keyword arguments"},
- {OPT_TRUE, "r", (char *) &reformat,
- "Force man page to be reformatted, even if up-to-date"},
- {OPT_STRING, "s", (char *) §ionName,
- "Section name in which to search for man page(s)"},
- {OPT_TRUE, "t", (char *) &typeset,
- "Print man page on typesetter instead of on terminal"},
- {OPT_TRUE, "w", (char *) &where,
- "Print where the man page was found"},
- {OPT_TRUE, "", (char *) &noMore,
- "Don't filter output through \"more\" program"},
- };
-
- /*
- * One of the data structures built up by this program is the one
- * that describes the directories containing man page sources, and
- * the corresponding directories containing pre-formatted man pages.
- */
-
- typedef struct {
- char *sourceDir; /* Directory holding man page sources. */
- char *fmtDir; /* Directory holding formatted entries,
- * by same name. */
- char *sectionName; /* Preferred name for this section of the
- * manual. */
- } ManDir;
-
- #define MAX_DIRS 100
- ManDir dirs[MAX_DIRS];
- int numDirs; /* Number of valid entries in dirs. */
-
- /*
- * The data structure below is used to hold all the index information
- * associated with a manual entry.
- */
-
- #define MAX_NAMES 100
- #define MAX_KEYWORDS 100
- #define NAME_CHARS 1000
- #define KEYWORD_CHARS 1000
- #define SYNOPSIS_CHARS 100
- #define FILE_CHARS 100
-
- typedef struct {
- char fileName[FILE_CHARS]; /* Base name of file containing man
- * page (everything up to "."). */
- char *names[MAX_NAMES+1]; /* Names of procedures or programs
- * described by this entry. These
- * fields come from the "NAME" manual
- * section. Terminated by a NULL
- * pointer. */
- char synopsis[SYNOPSIS_CHARS]; /* Short description of the entry.
- * Comes from the part of the "NAME"
- * section that follows the dash. */
- char *keywords[MAX_KEYWORDS+1]; /* Keywords associated with this
- * manual entry. Comes from the
- * "KEYWORD" section of the entry, if
- * there is one. Terminated by a
- * NULL pointer. */
- char nameBuffer[NAME_CHARS]; /* Storage space for names. */
- char keywordBuffer[KEYWORD_CHARS]; /* Storage space for keywords. */
- } IndexEntry;
-
- /*
- * Commands to use for formatting and printing manual pages. The %s's
- * in these commands get filled in with particular file names in the
- * code below.
- */
-
- #define FORMAT "nroff -man -Tcrt %s > %s"
- #define FORMAT_PRINT "nroff -man -Tcrt %s | %s -s"
- #define FORMAT_PRINT_NO_MORE "nroff -man -Tcrt %s"
- #define PRINT "%s -s %s"
- #define PRINT_NO_MORE "cat %s"
- #define TYPESET "ditroff -man %s"
-
- /*
- *----------------------------------------------------------------------
- *
- * NextLine --
- *
- * Read the next line of a given file, skipping comment lines.
- * Break the line up into fields separated by white space.
- *
- * Results:
- * The return value is the number of fields in the line (i.e. the
- * number of elements of argv that are now valid). If EOF was
- * encountered, then the return value is -1. The fields pointed
- * to by argv are allocated in static storage, so they'll only
- * be valid up until the next call to this procedure.
- *
- * Side effects:
- * The argv array is modified. If the line contains more fields than
- * are permitted by maxArgs, then an error message is output on stderr
- * and the extra fields are ignored.
- *
- *----------------------------------------------------------------------
- */
-
- int
- NextLine(file, maxArgs, argv)
- FILE *file; /* File from which to read. */
- int maxArgs; /* Number of entries in argv. */
- char **argv; /* Array to fill in with pointers to the
- * fields of the line. */
- {
- #define MAX_CHARS 200
- static char buffer[MAX_CHARS];
- register char *p;
- int i;
-
- while (1) {
- if (fgets(buffer, MAX_CHARS, file) == NULL) {
- return -1;
- }
- for (p = buffer; ; p++) {
- if (isspace(*p)) {
- continue;
- }
- if ((*p != '#') && (*p != 0)) {
- goto gotLine;
- }
- break;
- }
- }
-
- /*
- * Break the line up into fields.
- */
-
- gotLine:
- for (i = 0, p = buffer; ; i++) {
- while (isspace(*p)) {
- p++;
- }
- if (*p == 0) {
- return i;
- }
- if (i >= maxArgs) {
- break;
- }
- argv[i] = p;
- while (!isspace(*p)) {
- p++;
- }
- *p = 0;
- p++;
- }
-
- /*
- * Ran out of space to store field info.
- */
-
- fprintf(stderr,
- "More than %d fields in config file line; extras ignored.\n",
- maxArgs);
- return maxArgs;
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * ReadConfig --
- *
- * This procedure reads in the configuration file given by
- * name, and builds a list of all the directories that match
- * the given section.
- *
- * Results:
- * Zero is returned if all went well, -1 if there was an error.
- *
- * Side effects:
- * The dirs data structure is created. If an error occurred, then
- * an error message is printed.
- *
- *----------------------------------------------------------------------
- */
-
- int
- ReadConfig(name, section)
- char *name; /* Name of config file. */
- char *section; /* Only consider directories that match
- * this string; if NULL, consider
- * everything. */
- {
- #define MAX_FIELDS 50
- char *argv[MAX_FIELDS];
- FILE *f;
- int j, argc;
-
- f = fopen(name, "r");
- if (f == NULL) {
- fprintf(stderr, "Couldn't open \"%s\": %s.\n", name, strerror(errno));
- return -1;
- }
-
- for (numDirs = 0; numDirs < MAX_DIRS; ) {
- argc = NextLine(f, MAX_FIELDS, argv);
- if (argc < 0) {
- fclose(f);
- return 0;
- }
- for (j = 2; j < argc; j++) {
- if ((section == NULL) || (strcmp(argv[j], section) == 0)) {
- goto makeEntry;
- }
- }
- continue;
-
- /*
- * This line matched the section name; add an entry to dirs.
- */
-
- makeEntry:
- dirs[numDirs].sourceDir =
- (char *) malloc((unsigned) (strlen(argv[0]) + 1));
- strcpy(dirs[numDirs].sourceDir, argv[0]);
- dirs[numDirs].fmtDir =
- (char *) malloc((unsigned) (strlen(argv[1]) + 1));
- strcpy(dirs[numDirs].fmtDir, argv[1]);
- dirs[numDirs].sectionName =
- (char *) malloc((unsigned) (strlen(argv[2]) + 1));
- strcpy(dirs[numDirs].sectionName, argv[2]);
- numDirs++;
- }
-
- fprintf(stderr, "Too many lines in \"%s\": ignoring extras.\n", name);
- return 0;
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * FindSection --
- *
- * Advance a file just past the header line for a given section.
- *
- * Results:
- * Returns 0 if the given section was found, -1 if EOF was reached
- * before the desired section.
- *
- * Side effects:
- * Characters are read from file until a line is found in the form
- * ".SH section". The line and its terminating newline are read and
- * discarded.
- *
- *----------------------------------------------------------------------
- */
-
- int
- FindSection(file, section)
- FILE *file; /* File to read. */
- char *section; /* Section to search for. */
- {
- #define LINE_LENGTH 200
- char line[LINE_LENGTH];
- register char *p1, *p2;
-
- while (fgets(line, LINE_LENGTH, file) != NULL) {
- if ((line[0] != '.') || (line[1] != 'S') || (line[2] != 'H')) {
- continue;
- }
- for (p1 = &line[3]; isspace(*p1); p1++) {
- /* Skip white space. */
- }
- for (p2 = section; ; p1++, p2++) {
- if ((*p2 == 0) && ((*p1 == 0) || (isspace(*p1)))) {
- return 0;
- }
- if (*p2 != *p1) {
- break;
- }
- }
- }
- return -1;
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * IndexFromMan --
- *
- * Read the source file for a manual entry and generate an
- * index entry for it.
- *
- * Results:
- * Normally zero is returned, but if an error occurs then a
- * no-zero value is returned. *indexPtr is filled in with
- * information describing this man page.
- *
- * Side effects:
- * If an error occurs in reading the entry, then an error
- * message gets printed.
- *
- *----------------------------------------------------------------------
- */
-
- int
- IndexFromMan(fileName, indexPtr)
- char *fileName; /* Name of file containing man page. */
- register IndexEntry *indexPtr; /* Pointer to index entry. */
- {
- register FILE *file;
- register char *p;
- register int c;
- char *limit;
- int index;
-
- file = fopen(fileName, "r");
- if (file == NULL) {
- fprintf(stderr, "Couldn't open \"%s\": %s.\n", fileName,
- strerror(errno));
- return -1;
- }
-
- /*
- * Parse off the root of the file name.
- */
-
- for (p = fileName; (*p != '.') && (*p != 0); p++) {
- /* Null loop body. */
- }
- if ((p-fileName) > FILE_CHARS) {
- fprintf(stderr, "File name \"%s\" too long.\n", fileName);
- goto error;
- }
- strncpy(indexPtr->fileName, fileName, (p-fileName));
- indexPtr->fileName[p-fileName] = 0;
-
- /*
- * Parse off the names (a bunch of strings, all but the last of which
- * are terminated by commas, with the last terminated by space).
- */
-
- if (FindSection(file, "NAME") != 0) {
- fprintf(stderr, "Couldn't find \"NAME\" section in \"%s\".\n",
- fileName);
- goto error;
- }
- c = getc(file);
-
- /*
- * Skip any troff commands at the beginning of the section.
- */
-
- while (c == '.') {
- while ((c != '\n') && (c != EOF)) {
- c = getc(file);
- }
- c = getc(file);
- }
-
- /*
- * Parse off the procedure names.
- */
-
- p = indexPtr->nameBuffer;
- limit = &indexPtr->nameBuffer[NAME_CHARS-1];
- for (index = 0; index < MAX_NAMES; ) {
- while (isspace(c)) {
- c = getc(file);
- }
- indexPtr->names[index] = p;
- while (!isspace(c) && (c != ',') && (p < limit)) {
- *p = c;
- p++;
- c = getc(file);
- }
- if (p >= limit) {
- break;
- }
- if (indexPtr->names[index] != p) {
- *p = 0;
- p++;
- index++;
- }
- if (c != ',') {
- break;
- }
- c = getc(file);
- }
- if (c == EOF) {
- fprintf(stderr, "Unexpected end-of-file in NAME section of \"%s\".\n",
- fileName);
- goto error;
- }
- if ((index == MAX_NAMES) || (p >= limit)) {
- fprintf(stderr, "Too many names in \"%s\"; skipped the extras.\n",
- fileName);
- }
- indexPtr->names[index] = 0;
-
- /*
- * Skip up to and through a hyphen and any following space, then
- * use the rest of the line as a synopsis.
- */
-
- while ((c != '-') && (c != EOF)) {
- c = getc(file);
- }
- for (c = getc(file); isspace(c); c = getc(file)) {
- /* Null loop body. */
- }
- ungetc(c, file);
- fgets(indexPtr->synopsis, SYNOPSIS_CHARS, file);
- for (p = indexPtr->synopsis; *p != 0; p++) {
- if (*p == '\n') {
- *p = 0;
- break;
- }
- }
-
- /*
- * Skip to the keywords section and parse off the keywords in a
- * fashion similar to the names, except that (a) it's OK not to have
- * a KEYWORDS section, (b) it's OK to have space in a keyword, and
- * (c) the last keyword is terminated by newline.
- */
-
- if (FindSection(file, "KEYWORDS") != 0) {
- indexPtr->keywords[0] = NULL;
- goto done;
- }
- c = getc(file);
- p = indexPtr->keywordBuffer;
- limit = &indexPtr->keywordBuffer[KEYWORD_CHARS-1];
- for (index = 0; index < MAX_KEYWORDS; ) {
- while (isspace(c)) {
- c = getc(file);
- }
- indexPtr->keywords[index] = p;
- while ((c != ',') && (c != '\n') && (c != EOF) && (p < limit)) {
- *p = c;
- p++;
- c = getc(file);
- }
- if (p >= limit) {
- break;
- }
- if (indexPtr->keywords[index] != p) {
- *p = 0;
- p++;
- index++;
- }
- if (c == EOF) {
- fprintf(stderr,
- "Unexpected end-of-file in KEYWORDS section of \"%s\".\n",
- fileName);
- goto error;
- }
- if (c == '\n') {
- break;
- }
- c = getc(file);
- }
- if ((index == MAX_NAMES) || (p >= limit)) {
- fprintf(stderr, "Too many names in \"%s\"; skipped the extras.\n",
- fileName);
- }
- indexPtr->keywords[index] = 0;
-
- done:
- fclose(file);
- return 0;
-
- error:
- fclose(file);
- return -1;
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * PrintIndex --
- *
- * Read manual pages and print index entries on standard output.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Information gets printed on standard output. Error messages
- * may appear on stderr.
- *
- *----------------------------------------------------------------------
- */
-
- void
- PrintIndex(argc, argv)
- int argc; /* Number of files to read. */
- char **argv; /* Names of files to read. */
- {
- IndexEntry index;
- int i;
- char **p;
-
- for (i = 0; i < argc; i++) {
- if (IndexFromMan(argv[i], &index) != 0) {
- continue;
- }
- printf("%s\n", index.fileName);
- for (p = index.names; *p != 0; p++) {
- printf("%s, ", *p);
- }
- putchar('\n');
- printf("%s\n", index.synopsis);
- for (p = index.keywords; *p != 0; p++) {
- printf("%s, ", *p);
- }
- putchar('\n');
- }
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * ReadNextIndex --
- *
- * Given a handle for an index file created by PrintIndex, read
- * the next index entry from the file.
- *
- * Results:
- * Zero is returned if all went well; otherwise -1 is returned
- * and an error message is printed on stderr. The fields in
- * *indexPtr will be filled in with information describing this
- * index entry.
- *
- * Side effects:
- * The position in file is advanced.
- *
- *----------------------------------------------------------------------
- */
-
- int
- ReadNextIndex(file, indexPtr)
- FILE *file; /* File to read. */
- IndexEntry *indexPtr; /* Entry to fill in. */
- {
- register char *p;
- int i;
-
- /*
- * Read in the file name line.
- */
-
- if (fgets(indexPtr->fileName, FILE_CHARS, file) == NULL) {
- return -1;
- }
- for (p = indexPtr->fileName; *p != '\n'; p++) {
- if (*p == 0) {
- fprintf(stderr, "Filename line for \"%s\" too long.\n",
- indexPtr->fileName);
- return -1;
- }
- }
- *p = 0;
-
- /*
- * Read in and parse the keyword line.
- */
-
- if (fgets(indexPtr->nameBuffer, NAME_CHARS, file) == NULL) {
- fprintf(stderr, "End-of-file in name line for \"%s\".\n",
- indexPtr->fileName);
- return -1;
- }
- for (i = 0, p = indexPtr->nameBuffer; i < MAX_NAMES; ) {
- while (isspace(*p)) {
- p++;
- }
- indexPtr->names[i] = p;
- while ((*p != ',') && (*p != 0)) {
- p++;
- }
- if (p != indexPtr->names[i]) {
- i++;
- }
- if (*p == 0) {
- break;
- }
- *p = 0;
- p++;
- }
- indexPtr->names[i] = 0;
- if ((p[-1] != '\n') || (i == MAX_NAMES)) {
- fprintf(stderr, "Too many names for \"%s\".\n", indexPtr->fileName);
- return -1;
- }
-
- /*
- * Read in the synopsis line; there's no parsing to do.
- */
-
- if (fgets(indexPtr->synopsis, SYNOPSIS_CHARS, file) == NULL) {
- fprintf(stderr, "End-of-file in synopsis line for \"%s\".\n",
- indexPtr->fileName);
- return -1;
- }
- for (p = indexPtr->synopsis; *p != '\n'; p++) {
- if (*p == 0) {
- fprintf(stderr, "Synopsis line for \"%s\" too long.\n",
- indexPtr->fileName);
- return -1;
- }
- }
- *p = 0;
-
- /*
- * Read in and parse the keywords line.
- */
-
- if (fgets(indexPtr->keywordBuffer, KEYWORD_CHARS, file) == NULL) {
- fprintf(stderr, "End-of-file in keywords line for \"%s\".\n",
- indexPtr->fileName);
- return -1;
- }
- for (i = 0, p = indexPtr->keywordBuffer; i < MAX_KEYWORDS;) {
- while (isspace(*p)) {
- p++;
- }
- indexPtr->keywords[i] = p;
- while ((*p != ',') && (*p != 0)) {
- p++;
- }
- if (p != indexPtr->keywords[i]) {
- i++;
- }
- if (*p == 0) {
- break;
- }
- *p = 0;
- p++;
- }
- indexPtr->keywords[i] = 0;
- if ((p[-1] != '\n') || (i == MAX_KEYWORDS)) {
- fprintf(stderr, "Too many keywords for \"%s\".\n", indexPtr->fileName);
- return -1;
- }
- return 0;
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * PrettyPrintIndex --
- *
- * Print an index entry in human-readable form on standard output.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- void
- PrettyPrintIndex(indexPtr, section)
- IndexEntry *indexPtr; /* Entry to print. */
- char *section; /* Name to use for manual section. */
- {
- #define COLS_FOR_NAMES 24
- int i, numCols;
-
- numCols = 0;
- for (i = 0; indexPtr->names[i] != 0; i++) {
- if (i != 0) {
- fputs(", ", stdout);
- numCols += 2;
- }
- fputs(indexPtr->names[i], stdout);
- numCols += strlen(indexPtr->names[i]);
- }
- numCols += printf(" (%s) ", section);
- if (numCols < COLS_FOR_NAMES) {
- printf("%*c", COLS_FOR_NAMES-numCols, ' ');
- }
- printf("- %s\n", indexPtr->synopsis);
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * PrintByKeyword --
- *
- * Given a keyword, locate the index entries (if any) corresponding
- * to that keyword and print out each matching index entry.
- *
- * Results:
- * Information is printed for each index entry that contains
- * the keyword as a substring of the entry's name, synopsis, or
- * keyword fields. If no matching entry was found, then an
- * error message is printed.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- int
- PrintByKeyword(keyword)
- char *keyword; /* String to search for. */
- {
- int i, foundMatch;
- FILE *f;
- char **p;
- char indexName[400];
- IndexEntry index;
-
- foundMatch = 0;
- for (i = 0; i < numDirs; i++) {
- sprintf(indexName, "%.350s/index", dirs[i].sourceDir);
- f = fopen(indexName, "r");
- if (f == NULL) {
- continue;
- }
- while (ReadNextIndex(f, &index) == 0) {
- for (p = index.names; *p != 0; p++) {
- if (strstr(*p, keyword) != 0) {
- goto found;
- }
- }
- if (strstr(index.synopsis, keyword) != 0) {
- goto found;
- }
- for (p = index.keywords; *p != 0; p++) {
- if (strstr(*p, keyword) != 0) {
- goto found;
- }
- }
- continue;
-
- found:
- PrettyPrintIndex(&index, dirs[i].sectionName);
- foundMatch = 1;
- }
- fclose(f);
- }
- if (!foundMatch) {
- fprintf(stderr,
- "Couldn't find any manual entries related to \"%s\".\n",
- keyword);
- }
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * main --
- *
- * This is the main program, which runs the whole show.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Read the man page for details.
- *
- *----------------------------------------------------------------------
- */
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- int i, result;
- char srcName[500], fmtName[500];
- char command[1100];
- char *progName = argv[0];
- char *pager;
- struct stat srcStat, fmtStat;
- IndexEntry index;
-
- pager = getenv("PAGER");
- if(pager == 0) pager = "more";
-
- /*
- * Process command-line options and figure out what section to
- * look in.
- */
-
- result = 0;
- argc = Opt_Parse(argc, argv, optionArray, Opt_Number(optionArray), 0);
- if ((sectionName == NULL) && (argc > 1) && (isdigit(argv[1][0]))) {
- sectionName = argv[1];
- argc--;
- argv++;
- }
-
- /*
- * If we're just generating an index, do it here and quit.
- */
-
- if (makeIndex) {
- PrintIndex(argc-1, &argv[1]);
- exit(0);
- }
-
- /*
- * Read in the configuration file, and make sure that there is at
- * least one place to look for the desired manual page.
- */
-
- if (ReadConfig(configFile, sectionName) != 0) {
- exit(1);
- }
- if (numDirs == 0) {
- if (sectionName != NULL) {
- fprintf(stderr, "No manual section named \"%s\".\n", sectionName);
- } else {
- fprintf(stderr, "The config file (%s) is empty!\n", CONFIG_FILE);
- }
- exit(1);
- }
-
- if (argc == 1) {
- fprintf(stderr, "Usage: %s [options] entryName entryName ...\n",
- progName);
- exit(1);
- }
-
- /*
- * Loop over all of the named man pages, processing each one separately.
- */
-
- for (argv++ ; argc > 1; argc--, argv++) {
- /*
- * Handle special case of keyword lookup.
- */
-
- if (keywordLookup) {
- PrintByKeyword(argv[0]);
- continue;
- }
-
- /*
- * Search for the desired entry in two passes. In the first pass,
- * look in each of the available directories for a file named
- * "foo.man" where foo is the entry's name. If this doesn't work,
- * then the second pass reads the index files in each of the
- * available directories, checking for an entry with the desired
- * name.
- */
-
- for (i = 0; i < numDirs; i++) {
- sprintf(srcName, "%.350s/%.100s.man", dirs[i].sourceDir, argv[0]);
- if (access(srcName, R_OK) == 0) {
- sprintf(fmtName, "%.350s/%.100s.man", dirs[i].fmtDir, argv[0]);
- goto gotEntry;
- }
- }
- for (i = 0; i < numDirs; i++) {
- FILE *f;
- char **p;
-
- sprintf(srcName, "%.350s/index", dirs[i].sourceDir);
- f = fopen(srcName, "r");
- if (f == NULL) {
- continue;
- }
- while (ReadNextIndex(f, &index) == 0) {
- for (p = index.names; *p != 0; p++) {
- if (strcmp(*p, argv[0]) == 0) {
- sprintf(srcName, "%.350s/%.100s.man",
- dirs[i].sourceDir, index.fileName);
- if (access(srcName, R_OK) == 0) {
- sprintf(fmtName, "%.350s/%.100s.man",
- dirs[i].fmtDir, index.fileName);
- fclose(f);
- goto gotEntry;
- }
- }
- }
- }
- fclose(f);
- }
-
- /*
- * Couldn't find the manual entry.
- */
-
- if (sectionName == NULL) {
- fprintf(stderr, "No manual entry for \"%s\".\n", argv[0]);
- } else {
- fprintf(stderr,
- "No manual entry for \"%s\" in section \"%s\".\n",
- argv[0], sectionName);
- }
- result = 1;
- continue;
-
- /*
- * If the entry is to be typeset, just do it.
- */
-
- gotEntry:
- if (typeset) {
- sprintf(command, TYPESET, srcName);
- if (system(command) != 0) {
- printf("Error in typesetting \"%s\" man page.\n", argv[0]);
- result = 1;
- }
- continue;
- }
-
- /*
- * See if there is an up-to-date formatted version of the page.
- * If not, then regenerate it. (If the formatted directory is
- * "-" that means no formatted version of the man page is to be
- * kept)
- */
-
- if (strcmp(dirs[i].fmtDir, "-") == 0) {
- goto couldntFormat;
- }
- if ((stat(srcName, &srcStat) != 0) || (stat(fmtName, &fmtStat) != 0)
- || (srcStat.st_mtime > fmtStat.st_mtime) || reformat) {
- printf("Reformatting manual entry. Please wait...\n");
- sprintf(command, FORMAT, srcName, fmtName);
- if (system(command) != 0) {
- unlink(fmtName);
- goto couldntFormat;
- }
-
- /*
- * Reprotect the formatted file so that anyone can overwrite
- * it later.
- */
-
- chmod(fmtName, 0666);
- }
-
- /*
- * Print the formatted version of the man page.
- */
-
- if (where) {
- printf("Man page found in %s\n", fmtName);
- continue;
- }
- if (noMore) {
- sprintf(command, PRINT_NO_MORE, fmtName);
- } else {
- sprintf(command, PRINT, pager, fmtName);
- }
- if (system(command) == 0) {
- continue;
- }
-
- /*
- * We get here if it wasn't possible to format and/or print the
- * man page. Try one last desperation move: print and format
- * in a single command.
- */
-
- couldntFormat:
- if (noMore) {
- sprintf(command, FORMAT_PRINT_NO_MORE, srcName);
- } else {
- sprintf(command, FORMAT_PRINT, srcName, pager);
- }
- (void) system(command);
- }
- exit(result);
- }
- @
-
-
- 1.9
- log
- @Added recognition of PAGER environment variable instead of stupidly
- calling more
- @
- text
- @d18 1
- a18 1
- static char rcsid[] = "$Header: /sprite/src/cmds/man/RCS/man.c,v 1.9 91/01/08 21:26:28 tve Exp $ SPRITE (Berkeley)";
- d332 1
- a332 1
- if ((*p2 == 0) && ((*p1 == 0) || (*p1 == '\n'))) {
- d406 16
- @
-
-
- 1.8
- log
- @Ignore errors when formatting and printing at the same time.
- @
- text
- @d18 1
- a18 1
- static char rcsid[] = "$Header: /a/newcmds/man/RCS/man.c,v 1.7 89/01/13 17:03:53 ouster Exp $ SPRITE (Berkeley)";
- d56 1
- d73 2
- d136 1
- a136 1
- #define FORMAT_PRINT "nroff -man -Tcrt %s | more -s"
- d138 1
- a138 1
- #define PRINT "more -s %s"
- d821 1
- d825 3
- d988 4
- d995 1
- a995 1
- sprintf(command, PRINT, fmtName);
- d1011 1
- a1011 1
- sprintf(command, FORMAT_PRINT, srcName);
- @
-
-
- 1.7
- log
- @Don't print keywords in "-k" listings.
- @
- text
- @d18 1
- a18 1
- static char rcsid[] = "$Header: /a/newcmds/man/RCS/man.c,v 1.6 89/01/11 14:28:04 ouster Exp Locker: ouster $ SPRITE (Berkeley)";
- d1002 1
- a1002 5
- if (system(command) == 0) {
- continue;
- }
- result = 1;
- printf("Couldn't find a way to print \"%s\" man page.\n", argv[0]);
- @
-
-
- 1.6
- log
- @Allow "-" formatted directory to not keep formatted versions.
- @
- text
- @d18 1
- a18 1
- static char rcsid[] = "$Header: /a/newcmds/man/RCS/man.c,v 1.5 88/12/29 14:48:45 ouster Exp $ SPRITE (Berkeley)";
- d25 1
- d52 4
- d60 6
- d86 2
- d95 32
- d251 1
- a251 1
- int i, j, argc;
- d283 3
- d296 501
- d819 1
- d835 9
- d871 3
- d875 5
- d881 6
- a886 2
- * Scan through all of the matching sections, looking for the source
- * for the desired page.
- d892 2
- a893 1
- break;
- d896 8
- a903 7
- if (i >= numDirs) {
- if (sectionName == NULL) {
- fprintf(stderr, "No manual entry for \"%s\".\n", argv[0]);
- } else {
- fprintf(stderr,
- "No manual entry for \"%s\" in section \"%s\".\n",
- argv[0], sectionName);
- d905 15
- a919 2
- result = 1;
- continue;
- d923 1
- a923 1
- * If the page is to be typeset, just do it.
- d926 15
- a959 1
- sprintf(fmtName, "%.350s/%.100s.man", dirs[i].fmtDir, argv[0]);
- @
-
-
- 1.5
- log
- @Retain ".man" suffix on formatted man pages.
- @
- text
- @d18 1
- a18 1
- static char rcsid[] = "$Header: /a/newcmds/man/RCS/man.c,v 1.4 88/12/29 10:17:56 ouster Exp Locker: ouster $ SPRITE (Berkeley)";
- d337 1
- a337 1
- * If the page is to be typset, just do it.
- d351 3
- a353 1
- * If not, then regenerate it.
- d356 3
- @
-
-
- 1.4
- log
- @Don't put execute permission on formatted files.
- @
- text
- @d18 1
- a18 1
- static char rcsid[] = "$Header: /a/newcmds/man/RCS/man.c,v 1.3 88/12/29 09:40:37 ouster Exp Locker: ouster $ SPRITE (Berkeley)";
- d354 1
- a354 1
- sprintf(fmtName, "%.350s/%.100s", dirs[i].fmtDir, argv[0]);
- @
-
-
- 1.3
- log
- @Change in message wording.
- @
- text
- @d18 1
- a18 1
- static char rcsid[] = "$Header: /a/newcmds/man/RCS/man.c,v 1.2 88/12/28 16:34:38 ouster Exp Locker: ouster $ SPRITE (Berkeley)";
- d369 1
- a369 1
- chmod(fmtName, 0777);
- @
-
-
- 1.2
- log
- @First version of man now appears to be useable.
- @
- text
- @d18 1
- a18 1
- static char rcsid[] = "$Header: /a/newcmds/man/RCS/man.c,v 1.1 88/12/23 17:22:16 ouster Exp Locker: ouster $ SPRITE (Berkeley)";
- d357 1
- a357 1
- printf("Reformatting man page. Please wait...\n");
- @
-
-
- 1.1
- log
- @Initial revision
- @
- text
- @d18 1
- a18 1
- static char rcsid[] = "$Header: proto.c,v 1.2 88/03/11 08:39:08 ouster Exp $ SPRITE (Berkeley)";
- d26 3
- d31 8
- d47 4
- d53 4
- d82 3
- a84 1
- * Name of configuration file:
- d87 6
- a92 3
- #ifndef CONFIG_FILE
- #define CONFIG_FILE "/a/newcmds/man/config"
- #endif
- d265 5
- a269 1
- int i;
- d276 1
- d284 6
- a289 1
- if (ReadConfig(CONFIG_FILE, sectionName) != 0) {
- d301 4
- a304 3
- printf("Man will check the following directories:\n");
- for (i = 0; i < numDirs; i++) {
- printf(" %s %s\n", dirs[i].sourceDir, dirs[i].fmtDir);
- d306 98
- @
-